package com.tanklab.signature.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tanklab.signature.common.util.ChainUtils;
import com.tanklab.signature.common.util.HashUtil;
import com.tanklab.signature.common.util.ResultCode;
import com.tanklab.signature.common.util.TimeUtils;
import com.tanklab.signature.ds.resp.CommonResp;
import com.tanklab.signature.entity.*;
import com.tanklab.signature.eth.ChainConnection;
import com.tanklab.signature.mapper.*;
import com.tanklab.signature.service.ApprovalService;
import com.tanklab.signature.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class ApprovalServiceImpl extends ServiceImpl<ApprovallogsMapper, Approvallogs> implements ApprovalService {

    @Autowired
    private ApprovallogsMapper approvallogsMapper;

    @Autowired
    private RequestMapper requestMapper;

    @Autowired
    private FileMapper fileMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private ChainUtils chainUtils;

    @Autowired
    private UserService userService;

    @Autowired
    private UserSignatureMapper userSignatureMapper;

    @Override
    @Transactional
    public CommonResp approveRequest(Long requestId, String action, String comments, String openid) {
        CommonResp resp = new CommonResp();

        // 1. 查询申请是否存在
        Request request = requestMapper.selectById(requestId);
        if (request == null) {
            resp.setRet(ResultCode.NOT_MATCH_ERROR);
            resp.setMsg("申请不存在");
            return resp;
        }

        // 2. 检查申请状态
        if (!"pending".equals(request.getStatus())) {
            resp.setRet(ResultCode.NOT_MATCH_ERROR);
            resp.setMsg("该申请已被审批，状态: " + request.getStatus());
            return resp;
        }

        // 3. 获取当前用户和申请者信息
        User approver = getUserByOpenid(openid);
        User initiator = getUserByOpenid(request.getInitiatorOpenid());

        if (approver == null) {
            resp.setRet(ResultCode.USER_NOT_EXIST);
            resp.setMsg("审批用户不存在");
            return resp;
        }

        if (initiator == null) {
            resp.setRet(ResultCode.USER_NOT_EXIST);
            resp.setMsg("申请用户不存在");
            return resp;
        }

        // 4. 权限校验
        // 检查是否是自己的申请
        if (openid.equals(request.getInitiatorOpenid())) {
            resp.setRet(ResultCode.PERMISSION_DENIED);
            resp.setMsg("不能审批自己提交的申请");
            return resp;
        }

        // 检查权限级别
        if (approver.getAuthority() < initiator.getAuthority()) {
            resp.setRet(ResultCode.PERMISSION_DENIED);
            resp.setMsg("权限不足，无法审批该申请");
            return resp;
        }

        // 5. 检查审批者是否有签名
//        if (approver.getSignatureUrl() == null || approver.getSignatureUrl().isEmpty()) {
//            resp.setRet(ResultCode.PARAM_ERROR);
//            resp.setMsg("请先上传您的签名后再进行审批");
//            return resp;
//        }

        // 5. 检查审批者是否有签名
        UserSignature activeSignature = userService.getActiveSignature(openid);
        if (activeSignature == null) {
            resp.setRet(ResultCode.PARAM_ERROR);
            resp.setMsg("请先上传您的签名后再进行审批");
            return resp;
        }

        // 6. 获取关联文件
        File file = fileMapper.selectById(request.getFileId());
        if (file == null) {
            resp.setRet(ResultCode.NOT_MATCH_ERROR);
            resp.setMsg("关联文件不存在");
            return resp;
        }

        // 7. 创建审批记录
        String currentTime = TimeUtils.getCurrentTime();

        // 生成审批日志记录信息JSON
        JSONObject logsInfo = new JSONObject();
        logsInfo.put("requestId", requestId);
        logsInfo.put("approverOpenid", openid);
        logsInfo.put("approverSignatureUrl", activeSignature.getSignatureUrl());
        logsInfo.put("approverSignatureId", activeSignature.getId());
        logsInfo.put("action", action);
        logsInfo.put("actionTime", currentTime);
        logsInfo.put("comments", comments);
        logsInfo.put("fileId", file.getIdFile());
        logsInfo.put("fileName", file.getNameFile());

        // 计算审批记录哈希
        String approvalHash = HashUtil.hash_func(logsInfo.toString(), "MD5");

        // 将审批记录哈希上链
        String approvalTxId=chainUtils.sendHashToChain(approvalHash,"approvalHash");
//        try {
//            approvalTxId = ChainConnection.sendHashToChain(approvalHash);
//        } catch (ChainConnection.BlockchainException e) {
//            // 临时替代方案，使用固定值
//            approvalTxId = "114514-" + System.currentTimeMillis();
//        }

        // 8. 保存审批记录
        Approvallogs approvallogs = new Approvallogs();
        approvallogs.setIdRequest(requestId);
        approvallogs.setApproverOpenid(openid);
        approvallogs.setAction(action);
        approvallogs.setActionTime(currentTime);
        approvallogs.setComments(comments);
        approvallogs.setApprovallogsHash(approvalHash);
        approvallogs.setApprovallogsTxId(approvalTxId);
        approvallogs.setSignatureId(activeSignature.getId());

        approvallogsMapper.insert(approvallogs);

        // 9. 更新申请状态
        request.setStatus(action);
        request.setComments(comments);
        requestMapper.updateById(request);

        // 10. 返回成功消息
        resp.setRet(ResultCode.SUCCESS);
        resp.setMsg("审批成功");

        JSONObject data = new JSONObject();
        data.put("requestId", requestId);
        data.put("action", action);
        data.put("approvallogsHash", approvalHash);
        data.put("approvallogsTxId", approvalTxId);
        data.put("approverSignatureUrl", approver.getSignatureUrl());

        resp.setData(data);
        return resp;
    }

    @Override
    public CommonResp getPendingApprovals(String openid) {
        CommonResp resp = new CommonResp();

        // 获取用户信息
        User user = getUserByOpenid(openid);
        if (user == null) {
            resp.setRet(ResultCode.USER_NOT_EXIST);
            resp.setMsg("用户不存在");
            return resp;
        }

        // 查询待审批的申请
        List<Map<String, Object>> pendingList = new ArrayList<>();

        // 获取所有待审批的申请
        QueryWrapper<Request> requestQuery = new QueryWrapper<>();
        requestQuery.eq("status", "pending");
        List<Request> pendingRequests = requestMapper.selectList(requestQuery);

        for (Request req : pendingRequests) {
            // 跳过自己提交的申请
            if (openid.equals(req.getInitiatorOpenid())) {
                continue;
            }

            // 获取申请者信息
            User initiator = getUserByOpenid(req.getInitiatorOpenid());
            if (initiator == null) continue;

            // 检查权限
            if (user.getAuthority() < initiator.getAuthority()) {
                continue;  // 权限不足，跳过
            }

            // 获取文件信息
            File file = fileMapper.selectById(req.getFileId());
            if (file == null) continue;

            // 构造返回数据
            JSONObject requestData = new JSONObject();
            requestData.put("requestId", req.getIdRequest());
            requestData.put("requestName", req.getNameRequest());
            requestData.put("requestType", req.getTypeRequest());
            requestData.put("createdTime", req.getCreatedTime());
            requestData.put("fileId", file.getIdFile());
            requestData.put("fileName", file.getNameFile());
            requestData.put("fileType", file.getFileType());
            requestData.put("initiatorName", initiator.getUser_name());
            requestData.put("initiatorOpenid", initiator.getOpenid());

            pendingList.add(requestData);
        }

        resp.setRet(ResultCode.SUCCESS);
        resp.setData(pendingList);
        return resp;
    }

    @Override
    public CommonResp getApprovalHistory(String openid) {
        CommonResp resp = new CommonResp();

        // 查询用户审批过的记录
        QueryWrapper<Approvallogs> logsQuery = new QueryWrapper<>();
        logsQuery.eq("approver_openid", openid);
        logsQuery.orderByDesc("id_logs");

        List<Approvallogs> logs = approvallogsMapper.selectList(logsQuery);
        List<Map<String, Object>> historyList = new ArrayList<>();

        for (Approvallogs log : logs) {
            // 获取申请信息
            Request request = requestMapper.selectById(log.getIdRequest());
            if (request == null) continue;

            // 获取申请者信息
            User initiator = getUserByOpenid(request.getInitiatorOpenid());
            if (initiator == null) continue;

            // 获取文件信息
            File file = fileMapper.selectById(request.getFileId());
            if (file == null) continue;

            // 获取审批人信息和签名
            User approver = getUserByOpenid(log.getApproverOpenid());
//            String signatureUrl = approver != null ? approver.getSignatureUrl() : null;
            // 获取当时使用的签名
            String signatureUrl = null;
            if (log.getSignatureId() != null) {
                // 优先使用记录的签名ID
                UserSignature signature = userSignatureMapper.selectById(log.getSignatureId());
                if (signature != null) {
                    signatureUrl = signature.getSignatureUrl();
                }
            } else {
                // 兼容旧数据，使用用户当前签名
                signatureUrl = approver != null ? approver.getSignatureUrl() : null;
            }

            // 构造返回数据
            JSONObject logData = new JSONObject();
            logData.put("logId", log.getIdLogs());
            logData.put("requestId", log.getIdRequest());
            logData.put("requestName", request.getNameRequest());
            logData.put("action", log.getAction());
            logData.put("actionTime", log.getActionTime());
            logData.put("comments", log.getComments());
            logData.put("fileId", file.getIdFile());
            logData.put("fileName", file.getNameFile());
            logData.put("initiatorName", initiator.getUser_name());
            logData.put("approvallogsHash", log.getApprovallogsHash());
            logData.put("approvallogsTxId", log.getApprovallogsTxId());
            logData.put("signatureUrl", signatureUrl);  // 从用户表获取审批人的签名
            logData.put("signatureId", log.getSignatureId());

            historyList.add(logData);
        }

        resp.setRet(ResultCode.SUCCESS);
        resp.setData(historyList);
        return resp;
    }

    @Override
    public CommonResp getRequestApprovalLogs(Long requestId) {
        CommonResp resp = new CommonResp();

        // 查询申请的审批记录
        QueryWrapper<Approvallogs> logsQuery = new QueryWrapper<>();
        logsQuery.eq("id_request", requestId);
        logsQuery.orderByAsc("id_logs");

        List<Approvallogs> logs = approvallogsMapper.selectList(logsQuery);
        List<Map<String, Object>> logsList = new ArrayList<>();

        for (Approvallogs log : logs) {
            // 获取审批者信息
            User approver = getUserByOpenid(log.getApproverOpenid());
//            String signatureUrl = approver != null ? approver.getSignatureUrl() : null;
            // 获取当时使用的签名
            String signatureUrl = null;
            if (log.getSignatureId() != null) {
                // 优先使用记录的签名ID
                UserSignature signature = userSignatureMapper.selectById(log.getSignatureId());
                if (signature != null) {
                    signatureUrl = signature.getSignatureUrl();
                }
            } else if (approver != null) {
                // 兼容旧数据，使用用户当前签名
                signatureUrl = approver.getSignatureUrl();
            }

            // 构造返回数据
            JSONObject logData = new JSONObject();
            logData.put("logId", log.getIdLogs());
            logData.put("approverName", approver != null ? approver.getUser_name() : "未知用户");
            logData.put("approverOpenid", log.getApproverOpenid());
            logData.put("action", log.getAction());
            logData.put("actionTime", log.getActionTime());
            logData.put("comments", log.getComments());
            logData.put("approvallogsHash", log.getApprovallogsHash());
            logData.put("approvallogsTxId", log.getApprovallogsTxId());
            logData.put("signatureUrl", signatureUrl);
            logData.put("signatureId", log.getSignatureId());

            logsList.add(logData);
        }

        resp.setRet(ResultCode.SUCCESS);
        resp.setData(logsList);
        return resp;
    }

    /**
     * 根据openid获取用户
     */
    private User getUserByOpenid(String openid) {
        QueryWrapper<User> userQuery = new QueryWrapper<>();
        userQuery.eq("openid", openid);
        return userMapper.selectOne(userQuery);
    }
}